package org.mapdb.store

import org.junit.After
import org.junit.Test
import java.io.File
import java.util.*
import org.junit.Assert.*
import org.mapdb.DBException
import org.mapdb.TT
import org.mapdb.TT.assertFailsWith
import org.mapdb.ser.Serializers

abstract class StoreReopenTest(): StoreTest(){

    val file = TT.tempFile()

    @After fun deleteFiles(){
        TT.tempDelete(file);
    }


    abstract fun openStore(file: File): MutableStore

    abstract val headerType:Long

// TODO file headers
//
//    @Test open fun headerType(){
//        val s = openStore(file)
//        s.put(11L, Serializers.LONG)
//        s.commit()
//        s.close()
//        val vol = RandomAccessFileVol.FACTORY.makeVolume(file.path, true)
//        assertEquals(CC.FILE_HEADER,vol.getUnsignedByte(0L).toLong())
//        assertEquals(headerType, vol.getUnsignedByte(1L).toLong())
//    }



    @Test fun put_reopen_get() {
        var e = openStore(file)
        val l = 11231203099090L
        val recid = e.put(l, Serializers.LONG)
        e.commit()
        e.close()
        e = openStore(file)

        assertEquals(l, e.get(recid, Serializers.LONG))
        e.close()
    }


    @Test fun put_reopen_get_large() {
        var e = openStore(file)

        val b = TT.randomByteArray(1000000)
        val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE)
        e.commit()
        e.close()
        e = openStore(file)

        assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE)))
        e.verify()
        e.close()
    }

    @Test fun large_record_update2() {
        var e = openStore(file)
        val b = TT.randomByteArray(1000000)
        val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE)
        e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b)
        var b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE)
        assertTrue(Arrays.equals(b, b2))
        e.commit()
        e.close()
        e = openStore(file)

        b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE)
        assertTrue(Arrays.equals(b, b2))
        e.verify()
        e.close()
    }

    @Test fun large_record_larger() {
        var e = openStore(file)
        val b = TT.randomByteArray(100000000)
        val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE)
        var b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE)
        assertTrue(Arrays.equals(b, b2))
        e.verify()
        e.commit()
        e.close()
        e = openStore(file)

        b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE)
        assertTrue(Arrays.equals(b, b2))
        e.verify()
        e.close()
    }



    @Test fun test_store_reopen() {
        var e = openStore(file)
        val recid = e.put("aaa", Serializers.STRING)
        e.commit()
        e.commit()
        e.close()
        e = openStore(file)
        val aaa = e.get(recid, Serializers.STRING)
        assertEquals("aaa", aaa)
        e.verify()
        e.close()
    }


    @Test fun file_lock(){
        var e = openStore(file)
        val recid = e.put("aaa", Serializers.STRING)

        assertFailsWith(DBException.FileLocked::class) {
            openStore(file)
        }

        e.close()
    }
// TODO missing test
//    @Test fun empty_rollback2(){
//        val e = openStore(file)
//        if(e is StoreTx)
//            e.rollback()
//        e.close()
//    }

    @Test fun empty_commit2(){
        val e = openStore(file)
        e.commit()
        e.close()
    }



}